// 原始类型的类型标注
const name2: string = 'aaa'
const age: number  = 2
const male: boolean = false
const undef: undefined = undefined
const null2: null = null
const obj: object = {name: 'aaa', age: 2}
const bigintVar2: bigint = BigInt(9007199254740991)
const symbolVar: symbol = Symbol('unique')

// const temp2: string = null
const voidVar1: void = undefined

// 数组的类型标注
const arr1: string[] = []
const arr2: Array<string> = []

// 元组标注， 因为数组允许越界访问
const arr3: string[] = ['a', 'b', 'c']
console.log(arr3[4])

// 元组则不行
const arr4: [string, string, string] = ['a', 'b', 'c']
// console.log(arr4[5])

// 对象的类型标注
interface IDesc {
  name: string
  age: number
  male: boolean
}

const obj1:IDesc = {
  age: 14,
  male: false,
  name: 'aaa'
}

// 可选参数
interface IDesc2 {
  name: string
  age: number
  male?: boolean,
  func?: Function
}

const obj2: IDesc2 = {
  age: 1,
  male: false,
  name: '222'
}

obj2.male = false

// 可选参数被赋值后，类型推断任然是以声明时的类型为准

// 只读属性 readonly

interface IDesc3 {
  readonly name: string
  age: number
}

const obj3: IDesc3 = {
  name: 'lll',
  age: 23
}

// 只读属性不能被赋值
// obj3.name = '2222'

const tulple: readonly [string, string, string] = ['1', '2', '3']

// tulple[2] = '3'

// Object 类似的还有 Boolean、Number、String、Symbol，这几个装箱类型（Boxed Types） 
const tmp1: Object = undefined
const tmp2: Object = []
const tmp3: Object = 599

// 拆箱类型（Unboxed Types）
const tmp4: String= undefined
const tmp5: String= void 0